//! 统计工具模块
//! 
//! 提供各种统计计算功能

use serde::{Deserialize, Serialize};

/// 统计工具配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatsConfig {
    /// 置信水平
    pub confidence_level: f64,
    /// 是否进行异常值检测
    pub outlier_detection: bool,
    /// 异常值检测方法
    pub outlier_method: String,
}

/// 描述性统计结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DescriptiveStats {
    /// 样本数量
    pub count: usize,
    /// 均值
    pub mean: f64,
    /// 中位数
    pub median: f64,
    /// 标准差
    pub std: f64,
    /// 方差
    pub variance: f64,
    /// 最小值
    pub min: f64,
    /// 最大值
    pub max: f64,
    /// 偏度
    pub skewness: f64,
    /// 峰度
    pub kurtosis: f64,
}

/// 统计工具
#[derive(Debug, Clone)]
pub struct StatsUtils {
    config: StatsConfig,
}

impl StatsUtils {
    /// 创建新的统计工具
    pub fn new(config: StatsConfig) -> Self {
        Self { config }
    }

    /// 计算描述性统计
    pub fn descriptive_stats(&self, data: &[f64]) -> DescriptiveStats {
        if data.is_empty() {
            return DescriptiveStats {
                count: 0,
                mean: 0.0,
                median: 0.0,
                std: 0.0,
                variance: 0.0,
                min: 0.0,
                max: 0.0,
                skewness: 0.0,
                kurtosis: 0.0,
            };
        }
        
        let count = data.len();
        let mean = data.iter().sum::<f64>() / count as f64;
        let variance = data.iter()
            .map(|x| (x - mean).powi(2))
            .sum::<f64>() / count as f64;
        let std = variance.sqrt();
        
        let mut sorted_data = data.to_vec();
        sorted_data.sort_by(|a, b| a.partial_cmp(b).unwrap());
        let median = if count % 2 == 0 {
            (sorted_data[count/2 - 1] + sorted_data[count/2]) / 2.0
        } else {
            sorted_data[count/2]
        };
        
        let min = *sorted_data.first().unwrap();
        let max = *sorted_data.last().unwrap();
        
        let skewness = self.calculate_skewness(data, mean, std);
        let kurtosis = self.calculate_kurtosis(data, mean, std);
        
        DescriptiveStats {
            count,
            mean,
            median,
            std,
            variance,
            min,
            max,
            skewness,
            kurtosis,
        }
    }

    /// 计算偏度
    fn calculate_skewness(&self, data: &[f64], mean: f64, std: f64) -> f64 {
        if std == 0.0 || data.len() < 3 {
            return 0.0;
        }
        
        let n = data.len() as f64;
        let sum_cubed = data.iter()
            .map(|x| ((x - mean) / std).powi(3))
            .sum::<f64>();
        
        sum_cubed / n
    }

    /// 计算峰度
    fn calculate_kurtosis(&self, data: &[f64], mean: f64, std: f64) -> f64 {
        if std == 0.0 || data.len() < 4 {
            return 0.0;
        }
        
        let n = data.len() as f64;
        let sum_fourth = data.iter()
            .map(|x| ((x - mean) / std).powi(4))
            .sum::<f64>();
        
        sum_fourth / n - 3.0
    }

    /// 计算相关系数
    pub fn correlation(&self, x: &[f64], y: &[f64]) -> f64 {
        if x.len() != y.len() || x.is_empty() {
            return 0.0;
        }
        
        let n = x.len() as f64;
        let sum_x: f64 = x.iter().sum();
        let sum_y: f64 = y.iter().sum();
        let sum_xy: f64 = x.iter().zip(y.iter()).map(|(a, b)| a * b).sum();
        let sum_x2: f64 = x.iter().map(|a| a * a).sum();
        let sum_y2: f64 = y.iter().map(|a| a * a).sum();
        
        let numerator = n * sum_xy - sum_x * sum_y;
        let denominator = ((n * sum_x2 - sum_x * sum_x) * (n * sum_y2 - sum_y * sum_y)).sqrt();
        
        if denominator == 0.0 {
            0.0
        } else {
            numerator / denominator
        }
    }

    /// 计算协方差
    pub fn covariance(&self, x: &[f64], y: &[f64]) -> f64 {
        if x.len() != y.len() || x.is_empty() {
            return 0.0;
        }
        
        let n = x.len() as f64;
        let mean_x = x.iter().sum::<f64>() / n;
        let mean_y = y.iter().sum::<f64>() / n;
        
        x.iter().zip(y.iter())
            .map(|(a, b)| (a - mean_x) * (b - mean_y))
            .sum::<f64>() / n
    }

    /// 检测异常值 (使用IQR方法)
    pub fn detect_outliers(&self, data: &[f64]) -> Vec<usize> {
        if !self.config.outlier_detection || data.len() < 4 {
            return vec![];
        }
        
        let mut sorted_data = data.to_vec();
        sorted_data.sort_by(|a, b| a.partial_cmp(b).unwrap());
        
        let q1_idx = (data.len() as f64 * 0.25) as usize;
        let q3_idx = (data.len() as f64 * 0.75) as usize;
        
        let q1 = sorted_data[q1_idx];
        let q3 = sorted_data[q3_idx];
        let iqr = q3 - q1;
        
        let lower_bound = q1 - 1.5 * iqr;
        let upper_bound = q3 + 1.5 * iqr;
        
        data.iter().enumerate()
            .filter(|(_, &value)| value < lower_bound || value > upper_bound)
            .map(|(index, _)| index)
            .collect()
    }

    /// 计算分位数
    pub fn quantile(&self, data: &[f64], q: f64) -> f64 {
        if data.is_empty() || q < 0.0 || q > 1.0 {
            return 0.0;
        }
        
        let mut sorted_data = data.to_vec();
        sorted_data.sort_by(|a, b| a.partial_cmp(b).unwrap());
        
        let n = sorted_data.len() as f64;
        let index = (n * q) as usize;
        
        if index >= sorted_data.len() {
            sorted_data[sorted_data.len() - 1]
        } else {
            sorted_data[index]
        }
    }

    /// 计算置信区间
    pub fn confidence_interval(&self, data: &[f64]) -> (f64, f64) {
        if data.is_empty() {
            return (0.0, 0.0);
        }
        
        let stats = self.descriptive_stats(data);
        let z_score = 1.96; // 95% 置信水平对应的z值
        let margin_of_error = z_score * stats.std / (data.len() as f64).sqrt();
        
        (stats.mean - margin_of_error, stats.mean + margin_of_error)
    }

    /// 进行t检验
    pub fn t_test(&self, sample1: &[f64], sample2: &[f64]) -> (f64, f64) {
        if sample1.is_empty() || sample2.is_empty() {
            return (0.0, 1.0);
        }
        
        let stats1 = self.descriptive_stats(sample1);
        let stats2 = self.descriptive_stats(sample2);
        
        let pooled_variance = ((sample1.len() - 1) as f64 * stats1.variance + 
                              (sample2.len() - 1) as f64 * stats2.variance) / 
                             (sample1.len() + sample2.len() - 2) as f64;
        
        let t_statistic = (stats1.mean - stats2.mean) / 
                         (pooled_variance * (1.0 / sample1.len() as f64 + 1.0 / sample2.len() as f64)).sqrt();
        
        // 简化的p值计算 (实际应用中应使用更精确的方法)
        let p_value = if t_statistic.abs() > 2.0 { 0.05 } else { 0.5 };
        
        (t_statistic, p_value)
    }

    /// 计算移动平均
    pub fn moving_average(&self, data: &[f64], window: usize) -> Vec<f64> {
        if data.len() < window {
            return vec![];
        }
        
        let mut ma_values = Vec::new();
        for i in window - 1..data.len() {
            let sum: f64 = data[i - window + 1..=i].iter().sum();
            ma_values.push(sum / window as f64);
        }
        ma_values
    }

    /// 计算移动标准差
    pub fn moving_std(&self, data: &[f64], window: usize) -> Vec<f64> {
        if data.len() < window {
            return vec![];
        }
        
        let mut std_values = Vec::new();
        for i in window - 1..data.len() {
            let window_data = &data[i - window + 1..=i];
            let mean = window_data.iter().sum::<f64>() / window as f64;
            let variance = window_data.iter()
                .map(|x| (x - mean).powi(2))
                .sum::<f64>() / window as f64;
            std_values.push(variance.sqrt());
        }
        std_values
    }

    /// 计算z-score标准化
    pub fn z_score_normalize(&self, data: &[f64]) -> Vec<f64> {
        if data.is_empty() {
            return vec![];
        }
        
        let stats = self.descriptive_stats(data);
        if stats.std == 0.0 {
            return vec![0.0; data.len()];
        }
        
        data.iter()
            .map(|x| (x - stats.mean) / stats.std)
            .collect()
    }

    /// 生成统计报告
    pub fn generate_stats_report(&self, data: &[f64]) -> serde_json::Value {
        let stats = self.descriptive_stats(data);
        let outliers = self.detect_outliers(data);
        let (ci_lower, ci_upper) = self.confidence_interval(data);
        
        let unique_count = {
            let mut unique = data.to_vec();
            unique.sort_by(|a, b| a.partial_cmp(b).unwrap());
            unique.dedup();
            unique.len()
        };
        
        serde_json::json!({
            "descriptive_stats": {
                "count": stats.count,
                "mean": stats.mean,
                "median": stats.median,
                "std": stats.std,
                "variance": stats.variance,
                "min": stats.min,
                "max": stats.max,
                "skewness": stats.skewness,
                "kurtosis": stats.kurtosis
            },
            "quantiles": {
                "q25": self.quantile(data, 0.25),
                "q50": self.quantile(data, 0.50),
                "q75": self.quantile(data, 0.75)
            },
            "confidence_interval": {
                "lower": ci_lower,
                "upper": ci_upper,
                "confidence_level": self.config.confidence_level
            },
            "outlier_analysis": {
                "outlier_count": outliers.len(),
                "outlier_indices": outliers,
                "outlier_detection_enabled": self.config.outlier_detection
            },
            "data_quality": {
                "has_nan": data.iter().any(|x| x.is_nan()),
                "has_inf": data.iter().any(|x| x.is_infinite()),
                "unique_values": unique_count
            }
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_descriptive_stats() {
        let config = StatsConfig {
            confidence_level: 0.95,
            outlier_detection: true,
            outlier_method: "iqr".to_string(),
        };
        let stats_utils = StatsUtils::new(config);
        
        let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
        let stats = stats_utils.descriptive_stats(&data);
        
        assert_eq!(stats.count, 5);
        assert_eq!(stats.mean, 3.0);
        assert_eq!(stats.median, 3.0);
        assert_eq!(stats.min, 1.0);
        assert_eq!(stats.max, 5.0);
    }

    #[test]
    fn test_correlation() {
        let config = StatsConfig {
            confidence_level: 0.95,
            outlier_detection: true,
            outlier_method: "iqr".to_string(),
        };
        let stats_utils = StatsUtils::new(config);
        
        let x = vec![1.0, 2.0, 3.0, 4.0, 5.0];
        let y = vec![2.0, 4.0, 6.0, 8.0, 10.0];
        let correlation = stats_utils.correlation(&x, &y);
        
        assert!((correlation - 1.0).abs() < 1e-10);
    }

    #[test]
    fn test_detect_outliers() {
        let config = StatsConfig {
            confidence_level: 0.95,
            outlier_detection: true,
            outlier_method: "iqr".to_string(),
        };
        let stats_utils = StatsUtils::new(config);
        
        let data = vec![1.0, 2.0, 3.0, 4.0, 5.0, 100.0];
        let outliers = stats_utils.detect_outliers(&data);
        
        assert!(!outliers.is_empty());
        assert_eq!(outliers[0], 5); // 100.0 是异常值
    }

    #[test]
    fn test_moving_average() {
        let config = StatsConfig {
            confidence_level: 0.95,
            outlier_detection: true,
            outlier_method: "iqr".to_string(),
        };
        let stats_utils = StatsUtils::new(config);
        
        let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
        let ma = stats_utils.moving_average(&data, 3);
        
        assert_eq!(ma.len(), 3);
        assert_eq!(ma[0], 2.0); // (1+2+3)/3
        assert_eq!(ma[1], 3.0); // (2+3+4)/3
        assert_eq!(ma[2], 4.0); // (3+4+5)/3
    }
} 